﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace com.nm.library.Helper
{
   /// <summary>
   /// 
   /// </summary>
   public static class DataTableHelper
    {
        /// <summary>
        /// 将IEnumerable<T>类型的集合转换为DataTable类型 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="varlist"></param>
        /// <returns></returns>
        public static DataTable LinqToDataTable<T>(IEnumerable<T> varlist)
        {   //定义要返回的DataTable对象
            var dtReturn = new DataTable();
            // 保存列集合的属性信息数组
            PropertyInfo[] oProps = null;
            if (varlist == null) return dtReturn;//安全性检查
                                                 //循环遍历集合，使用反射获取类型的属性信息
            foreach (T rec in varlist)
            {
                //使用反射获取T类型的属性信息，返回一个PropertyInfo类型的集合
                if (oProps == null)
                {
                    oProps = ((Type)rec.GetType()).GetProperties();
                    //循环PropertyInfo数组
                    foreach (var pi in oProps)
                    {
                        var colType = pi.PropertyType;//得到属性的类型
                                                      //如果属性为泛型类型
                        if ((colType.IsGenericType) && (colType.GetGenericTypeDefinition()
                        == typeof(Nullable<>)))
                        {   //获取泛型类型的参数
                            colType = colType.GetGenericArguments()[0];
                        }
                        //将类型的属性名称与属性类型作为DataTable的列数据
                        dtReturn.Columns.Add(new DataColumn(pi.Name, colType));
                    }
                }
                //新建一个用于添加到DataTable中的DataRow对象
                var dr = dtReturn.NewRow();
                //循环遍历属性集合
                foreach (PropertyInfo pi in oProps)
                {   //为DataRow中的指定列赋值
                    dr[pi.Name] = pi.GetValue(rec, null) == null ?
                        DBNull.Value : pi.GetValue(rec, null);
                }
                //将具有结果值的DataRow添加到DataTable集合中
                dtReturn.Rows.Add(dr);
            }
            return dtReturn;//返回DataTable对象
        }
    }

    /// <summary>
    /// DataTable转List
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class ModelConvertHelper<T> where T : new()
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static IList<T> ConvertToModel(DataTable dt)
        {
            IList<T> ts = new List<T>();// 定义集合
            try
            {
                foreach (DataRow dr in dt.Rows)
                {
                    var t = new T();
                    var propertys = t.GetType().GetProperties(); // 获得此模型的公共属性
                    foreach (var pi in propertys)
                    {
                        var tempName = pi.Name;
                        if (!dt.Columns.Contains(tempName)) continue;
                        if (!pi.CanWrite) continue;
                        var value = dr[tempName];
                        if (value == DBNull.Value) continue;
                        if (pi.GetMethod.ReturnParameter != null && pi.GetMethod.ReturnParameter.ParameterType.Name == "Int32")
                        {
                            value = Convert.ToInt32(value);
                        }
                        pi.SetValue(t, value, null);
                    }
                    ts.Add(t);
                }
            }
            catch (Exception ex)
            {
                Log.Error(ex);
                throw (ex);
            }
            return ts;
        }

        public static T DataSetToEntity(DataSet ds)
        {
            try
            {
                if (ds == null || ds.Tables.Count < 0)
                    return default(T);
                if (0 > ds.Tables.Count - 1)
                    return default(T);
                if (ds.Tables[0].Rows.Count <= 0)
                    return default(T);
                DataRow p_Data = ds.Tables[0].Rows[0];
                // 返回值初始化
                T _t = (T)Activator.CreateInstance(typeof(T));
                PropertyInfo[] propertys = _t.GetType().GetProperties();
                foreach (PropertyInfo pi in propertys)
                {
                    if (ds.Tables[0].Columns.IndexOf(pi.Name.ToUpper()) != -1 &&
                        p_Data[pi.Name.ToUpper()] != DBNull.Value)
                    {
                        pi.SetValue(_t, p_Data[pi.Name.ToUpper()], null);
                    }
                    else
                    {
                        pi.SetValue(_t, null, null);
                    }
                }
                return _t;
            }
            catch (Exception ex)
            {
                Log.Error(ex);
                throw (ex);
            }
        }
    }
}
